#pragma once
#include <boost/asio.hpp>
#include "protocol.h"
#include <vector>
#include <list>
using namespace boost::asio;
using namespace boost::posix_time;

namespace NOEXIT
{



	struct SHeartBeat
	{
		ip::udp::endpoint clientEndPoint;
		char lostCount;//5 means dead
		SHeartBeat(ip::udp::endpoint clientAddr)
			:clientEndPoint(clientAddr),lostCount(0)
		{}

	};



	struct Session
	{
		SHeartBeat connectionInfo;
		int sessionId;
		long long clientGuaranteeOrder;
		long long serverGuaranteeOrder;

		PlayerInfo pinfo;

		Session(SHeartBeat conn, int _sessionId = -1):
		connectionInfo(conn),sessionId(_sessionId),clientGuaranteeOrder(0),serverGuaranteeOrder(0),
			pinfo(PlayerInfo(_sessionId))
		{
		}
	};

	class CServer
	{
	public:
		CServer();
		~CServer();
		void start();
		void startReceive();
		void MsgHandler(const boost::system::error_code& ec,std::size_t bytes_transferred);
		void SendBackMsgHandler(const boost::system::error_code& ec,std::size_t bytes_transferred);

		Session* getSessionById(int id);
		Session* getSessionByClient(ip::udp::endpoint client);

		void clearGuaranteeMsgs(SMsg* msg);
		void startSend_Guarantee();
		void startSend();
		
		float getRand(float start, float end);
		
		//logic
		std::vector<Session>::iterator playerLeaveGame(int sessionId);
	private:
		io_service service;
		int sessionCount;
		int bulletCount;
		ip::udp::endpoint address;
		ip::udp::socket* serverSocket;
		std::vector<Session> g_session_list;
		std::list<BulletInfo> bullets_list;

		ip::udp::endpoint client_address;
		char byteData[BUFFSIZE];
		char sendBackData[BUFFSIZE];


		std::vector<SMsg> NeedToSend;
		std::vector<SMsg> NeedToSend_Guarantee;
		bool GuaranteeSendFlag;
		ptime startpt;


	};
}
